{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "UNet2DModel(\n",
      "  (conv_in): Conv2d(3, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "  (time_proj): Timesteps()\n",
      "  (time_embedding): TimestepEmbedding(\n",
      "    (linear_1): Linear(in_features=128, out_features=512, bias=True)\n",
      "    (act): SiLU()\n",
      "    (linear_2): Linear(in_features=512, out_features=512, bias=True)\n",
      "  )\n",
      "  (class_embedding): Embedding(102, 512)\n",
      "  (down_blocks): ModuleList(\n",
      "    (0): DownBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "      )\n",
      "      (downsamplers): ModuleList(\n",
      "        (0): Downsample2D(\n",
      "          (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (1): DownBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "      )\n",
      "      (downsamplers): ModuleList(\n",
      "        (0): Downsample2D(\n",
      "          (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (2): DownBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(128, 256, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "      )\n",
      "      (downsamplers): ModuleList(\n",
      "        (0): Downsample2D(\n",
      "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (3): DownBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "      )\n",
      "      (downsamplers): ModuleList(\n",
      "        (0): Downsample2D(\n",
      "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (4): AttnDownBlock2D(\n",
      "      (attentions): ModuleList(\n",
      "        (0): AttentionBlock(\n",
      "          (group_norm): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (query): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (key): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (value): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (proj_attn): Linear(in_features=512, out_features=512, bias=True)\n",
      "        )\n",
      "        (1): AttentionBlock(\n",
      "          (group_norm): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (query): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (key): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (value): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (proj_attn): Linear(in_features=512, out_features=512, bias=True)\n",
      "        )\n",
      "      )\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "      )\n",
      "      (downsamplers): ModuleList(\n",
      "        (0): Downsample2D(\n",
      "          (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (5): DownBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "  )\n",
      "  (up_blocks): ModuleList(\n",
      "    (0): UpBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 1024, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(1024, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 1024, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(1024, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (2): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 1024, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(1024, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "      )\n",
      "      (upsamplers): ModuleList(\n",
      "        (0): Upsample2D(\n",
      "          (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (1): AttnUpBlock2D(\n",
      "      (attentions): ModuleList(\n",
      "        (0): AttentionBlock(\n",
      "          (group_norm): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (query): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (key): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (value): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (proj_attn): Linear(in_features=512, out_features=512, bias=True)\n",
      "        )\n",
      "        (1): AttentionBlock(\n",
      "          (group_norm): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (query): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (key): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (value): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (proj_attn): Linear(in_features=512, out_features=512, bias=True)\n",
      "        )\n",
      "        (2): AttentionBlock(\n",
      "          (group_norm): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (query): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (key): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (value): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (proj_attn): Linear(in_features=512, out_features=512, bias=True)\n",
      "        )\n",
      "      )\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 1024, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(1024, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 1024, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(1024, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (2): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 768, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(768, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "          (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(768, 512, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "      )\n",
      "      (upsamplers): ModuleList(\n",
      "        (0): Upsample2D(\n",
      "          (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (2): UpBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 768, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(768, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(768, 256, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(512, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (2): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(512, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "      )\n",
      "      (upsamplers): ModuleList(\n",
      "        (0): Upsample2D(\n",
      "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (3): UpBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(512, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(512, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (2): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 384, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=256, bias=True)\n",
      "          (norm2): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(384, 256, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "      )\n",
      "      (upsamplers): ModuleList(\n",
      "        (0): Upsample2D(\n",
      "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (4): UpBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 384, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(384, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(384, 128, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (2): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "      )\n",
      "      (upsamplers): ModuleList(\n",
      "        (0): Upsample2D(\n",
      "          (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "    (5): UpBlock2D(\n",
      "      (resnets): ModuleList(\n",
      "        (0): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (1): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "        (2): ResnetBlock2D(\n",
      "          (norm1): GroupNorm(32, 256, eps=1e-05, affine=True)\n",
      "          (conv1): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (time_emb_proj): Linear(in_features=512, out_features=128, bias=True)\n",
      "          (norm2): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "          (dropout): Dropout(p=0.0, inplace=False)\n",
      "          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "          (nonlinearity): SiLU()\n",
      "          (conv_shortcut): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))\n",
      "        )\n",
      "      )\n",
      "    )\n",
      "  )\n",
      "  (mid_block): UNetMidBlock2D(\n",
      "    (attentions): ModuleList(\n",
      "      (0): AttentionBlock(\n",
      "        (group_norm): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "        (query): Linear(in_features=512, out_features=512, bias=True)\n",
      "        (key): Linear(in_features=512, out_features=512, bias=True)\n",
      "        (value): Linear(in_features=512, out_features=512, bias=True)\n",
      "        (proj_attn): Linear(in_features=512, out_features=512, bias=True)\n",
      "      )\n",
      "    )\n",
      "    (resnets): ModuleList(\n",
      "      (0): ResnetBlock2D(\n",
      "        (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "        (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "        (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "        (dropout): Dropout(p=0.0, inplace=False)\n",
      "        (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        (nonlinearity): SiLU()\n",
      "      )\n",
      "      (1): ResnetBlock2D(\n",
      "        (norm1): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "        (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        (time_emb_proj): Linear(in_features=512, out_features=512, bias=True)\n",
      "        (norm2): GroupNorm(32, 512, eps=1e-05, affine=True)\n",
      "        (dropout): Dropout(p=0.0, inplace=False)\n",
      "        (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "        (nonlinearity): SiLU()\n",
      "      )\n",
      "    )\n",
      "  )\n",
      "  (conv_norm_out): GroupNorm(32, 128, eps=1e-05, affine=True)\n",
      "  (conv_act): SiLU()\n",
      "  (conv_out): Conv2d(128, 3, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "from yldiffusers import conditional_flower_ddpm_config_dict, get_config, DDPMConfig\n",
    "config = get_config(conditional_flower_ddpm_config_dict, DDPMConfig)\n",
    "print(config.model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "🚀yl-diffusion-DDPM training start!\n"
     ]
    },
    {
     "data": {
      "text/plain": "train : Epoch [1/4]:   0%|          | 0/16 [00:00<?, ?it/s<class 'dict'>]",
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "a853044648a84a5ca6fbaedf1f8ec7da"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001B[34m\u001B[1mtrain: \u001B[0mEpoch [1/4] total_mean_loss:1.0456\n"
     ]
    },
    {
     "data": {
      "text/plain": "train : Epoch [2/4]:   0%|          | 0/16 [00:00<?, ?it/s<class 'dict'>]",
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "a82ae1ea06704b5a9ef635b32b05bc09"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": "  0%|          | 0/500 [00:00<?, ?it/s]",
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "7d3c11deb55e4816b2a92e433d90eab8"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "🚀yl-diffusion-DDPM best model has saved!\n",
      "\u001B[34m\u001B[1mtrain: \u001B[0mEpoch [2/4] total_mean_loss:0.5527\n"
     ]
    },
    {
     "data": {
      "text/plain": "train : Epoch [3/4]:   0%|          | 0/16 [00:00<?, ?it/s<class 'dict'>]",
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "ef637c38a3224cc6b6dd43b6a61158d3"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001B[34m\u001B[1mtrain: \u001B[0mEpoch [3/4] total_mean_loss:0.1919\n"
     ]
    },
    {
     "data": {
      "text/plain": "train : Epoch [4/4]:   0%|          | 0/16 [00:00<?, ?it/s<class 'dict'>]",
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "03e1c4075f9a446886c4a75286d33661"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": "  0%|          | 0/500 [00:00<?, ?it/s]",
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "3347f64edd79437fb1f0bed57b6c1c26"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "🚀yl-diffusion-DDPM best model has saved!\n",
      "\u001B[34m\u001B[1mtrain: \u001B[0mEpoch [4/4] total_mean_loss:0.14\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x432 with 1 Axes>",
      "image/png": "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45BDDuGEE06gZcuW223nk08+4dFHH+Wee+5h4MCBPPXUUwwaNKjc33vGGWdw6623cuSRRzJmzBjGjRvHpEmTuO666/j0009p0KDBj4esJk6cyO23307Pnj0pKiqisLCwmv8y2+T1nkNREbz+equ4yxCRLNOjR4/thoXecsstHHTQQRx66KF88cUXfPLJJ6Xe065dO7p06QJAt27dWLp0abnbX716NatWreLII48E4Mwzz+S1114DoHPnzpx22mk8/PDD1K0bvt/37NmTCy+8kFtuuYVVq1b9uL4m8nrP4brrYMKEThx9NPToEXc1IlKZir7hV8WaNetqdJ1D4l1QZ86cycsvv8y//vUvGjVqRK9evcocNtqgQYMfHxcUFFR6WKk8L774Iq+99hrPP/8848eP580332TUqFEce+yxTJs2jZ49ezJ9+nT233//am2/WF7vOVxyCbRsuZEhQ2DTprirEZFM1LRp0wqP4a9evZoddtiBRo0asWDBAt56660a/87mzZuzww478PrrrwPw0EMPceSRR7J161a++OILevfuzfXXX8/q1aspKipi8eLFHHjggVx66aUccsghLFiwoMY15HU4NGsGw4d/wgcfpO4biYjklpYtW9KzZ08OOOAARo4cWer1Pn36sHnzZjp06MCoUaM49NBDU/J7H3jgAUaOHEnnzp15//33GTNmDFu2bGHQoEEceOCBdO3alT/84Q+0aNGCSZMmccABB9C5c2fq1avHMcccU/MC3D3rl27dunl1vfLKDO/Xz71hQ/clS6q9mYwwY8aMuEtImVzpS670wz2+vsyfPz/l2/z+++9Tvs24JNuXsv4dgVlezudqXu85AJjBbbdBQQGcdx5oSm0RkTw/rFRs993h2mvh73+Hxx6LuxoRkfgpHCLDhkH37jBiBETXmoiI5C2FQ6SgAO6+G779Fi69NO5qRCSR63hvjVTn30/hkKBr13AF5j33QDSCTERiVlhYyLfffquAqCaP5nOo6lXTeX0RXFnGjYMnn4RzzoH33oOE61ZEJAZt2rRh2bJlrFixImXbXL9+fUpuMZEJkulL8UxwVaFwKKFxY5g8GY49Fm64Aa68Mu6KRPJbvXr1qjSDWTJmzpxJ165dU7rNuNRWX3RYqQx9+8LAgTB+PHz8cdzViIikX1rDwczuM7OvzWxuOa+bmd1iZovM7EMz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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "🚀yl-diffusion-DDPM training end! total time:0.015 hours!\n"
     ]
    }
   ],
   "source": [
    "from yldiffusers import DDPM\n",
    "ddpm = DDPM(config)\n",
    "ddpm.train()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import glob\n",
    "from PIL import Image\n",
    "sample_images = sorted(glob.glob(f\"{config.output_dir}/samples/*.png\"))\n",
    "Image.open(sample_images[-1])"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}